using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Threading;

namespace cb0tServer
{
    class Bans
    {
        private static Mutex mutex = new Mutex();
        private static List<BannedUserItem> banned_items = new List<BannedUserItem>();

        public static void AddBan(UserObject userobj)
        {
            foreach (BannedUserItem a in banned_items)
            {
                if (userobj.physical_ip.Equals(a.ip) || userobj.guid.Equals(a.guid))
                {
                    return;
                }
            }

            BannedUserItem al = new BannedUserItem();
            al.name = userobj.name;
            al.ip = userobj.physical_ip;
            al.guid = userobj.guid;
            banned_items.Add(al);
            SaveBans();
        }

        public static String RemoveBan(ushort _id)
        {
            if (_id < banned_items.Count)
            {
                String str = banned_items[_id].name;
                banned_items.RemoveAt(_id);
                SaveBans();
                return str;
            }

            return null;
        }

        public static BannedUserItem[] GetBans()
        {
            if (banned_items.Count > 0)
            {
                return banned_items.ToArray();
            }

            return null;
        }

        public static bool IsBanned(UserObject userobj)
        {
            foreach (BannedUserItem a in banned_items)
            {
                if (userobj.physical_ip.Equals(a.ip) || userobj.guid.Equals(a.guid))
                {
                    return true;
                }
            }

            return false;
        }

        public static bool IsLinkBanned(UserObject userobj)
        {
            foreach (BannedUserItem a in banned_items)
            {
                if (userobj.physical_ip.Equals(a.ip))
                {
                    return true;
                }
            }

            return false;
        }

        public static void ClearBans()
        {
            banned_items.Clear();
            SaveBans();
        }
        
        public static void LoadBans()
        {
            banned_items.Clear();

            if (!File.Exists(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/bans.xml")) return;

            try
            {
                FileStream f = new FileStream(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/bans.xml", FileMode.Open);
                XmlReader xml = XmlReader.Create(new StreamReader(f));

                xml.MoveToContent();
                xml.ReadSubtree().ReadToFollowing("bans");

                while (xml.ReadToFollowing("ban"))
                {
                    BannedUserItem a = new BannedUserItem();

                    xml.ReadSubtree().ReadToFollowing("guid");
                    a.guid = new Guid(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("name");
                    a.name = Encoding.UTF8.GetString(Convert.FromBase64String(xml.ReadElementContentAsString()));
                    xml.ReadToFollowing("ip");
                    a.ip = new IPAddress(Convert.FromBase64String(xml.ReadElementContentAsString()));

                    banned_items.Add(a);
                }

                xml.Close();
                f.Flush();
                f.Close();
            }
            catch { }
        }

        private static void SaveBans()
        {
            mutex.WaitOne();

            try
            {
                XmlWriterSettings appearance = new XmlWriterSettings();
                appearance.Indent = true;
                XmlWriter xml = XmlWriter.Create(sb0t_winGUI.RunOnceFileUpdater.sbotpath + "data/bans.xml", appearance);

                xml.WriteStartDocument();
                xml.WriteStartElement("bans");

                foreach (BannedUserItem a in banned_items)
                {
                    xml.WriteStartElement("ban");
                    xml.WriteElementString("guid", Convert.ToBase64String(a.guid.ToByteArray()));
                    xml.WriteElementString("name", Convert.ToBase64String(Encoding.UTF8.GetBytes(a.name)));
                    xml.WriteElementString("ip", Convert.ToBase64String(a.ip.GetAddressBytes()));
                    xml.WriteEndElement();
                }

                xml.WriteEndElement();
                xml.WriteEndDocument();
                xml.Flush();
                xml.Close();
            }
            catch { }

            mutex.ReleaseMutex();
        }
    }

    class BannedUserItem
    {
        public String name;
        public IPAddress ip;
        public Guid guid;
    }
}
